package com.slipper.util;

import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.net.NetUtil;

import java.util.concurrent.ThreadLocalRandom;

public class UUID {
    private static final Object lock = new Object();
    private static String flag = null;
    private static String currHexTime = null;
    private static int currSeq = 1;

    /**
     * uuid获取，20位UUID：12位16进制时间 + 2位机器码 + 6位16进制序
     */
    public static String getUUID() {
        synchronized(lock) {
            String time = Long.toHexString(System.currentTimeMillis());
            if (time.equals(currHexTime)) {
                currSeq += 1;
            } else {
                currHexTime = time;
                currSeq = randomNumber();
            }
            String prefix = Tool.fillLength(time, 12, '0');
            String flag = getFlag();
            String seq = Integer.toHexString(currSeq);
            return prefix + flag + Tool.fillLength(seq, 20 - prefix.length() - flag.length(), '0');
        }
    }

    private static int randomNumber() {
        return ThreadLocalRandom.current().nextInt(1000000, 5000000);
    }

    /**
     * 32位uuid获取
     */
    public static String getUUID32() {
        return java.util.UUID.randomUUID().toString().replaceAll("-", "");
    }

    public static String getFlag() {
        if (Tool.isBlank(flag)) {
            flag = Tool.fillLength(getFlag(99L), 2, '0');
        }
        return flag;
    }

    public static String getFlag(long maxId) {
        if (maxId == Long.MAX_VALUE) {
            --maxId;
        }

        long id = 1L;
        byte[] mac = null;

        try {
            mac = NetUtil.getLocalHardwareAddress();
        } catch (UtilException ignored) {
        }

        if (null != mac) {
            id = (255L & (long)mac[mac.length - 2] | 65280L & (long)mac[mac.length - 1] << 8) >> 6;
            id %= maxId + 1L;
        }

        return id + "";
    }
}
